﻿#ifndef Header_Guard_GUID__1DCF1EEF_661E_499A_AE94_F2D15D4299D3
#define Header_Guard_GUID__1DCF1EEF_661E_499A_AE94_F2D15D4299D3

/// @file jjwf/srcs/xutility/gb_conv_internal.hpp
///
/// @brief 提供一些关于GB编码的内部实现，不对外开放接口
///   1. GB与WCHAR之间的转换，不依赖任何其他库
///   2. 提供GB的一些功能辅助函数

#include <cstdint>
#include <string>

std::wstring _gb_to_wstr(const std::string& strgb);
std::string  _wstr_to_gb(const std::wstring& wstr);

/**
 * @name gb编码辅助工具函数
 *
 * 中文区域多字节编码, 分为单字节、双字节、四字节三类:
 *
 *    一、单字节：[0x00,0x7F]   128英文字符+欧元符号
 *
 *    二、双字节:
 *    	1. GB2312汉字区:
 *    	  	[0xB0-0xF7] [0xA1-0xFE] 6768码位，6763汉字字符
 *    	2. GBK扩充汉字GB130001.的CJK汉字
 *    	  	[0x81-0xA0] [0x40-0xFE] 6080码位，6080汉字字符，第二字节不能包含 0x7F
 *    	3. GBK扩充汉字CJK汉字和增补的汉字
 *    	  	[0xAA-0xFE] [0x40-0xA0] 8160码位，8160汉字字符
 *    	4. GBK/1 非汉字符号区
 *    		[A1A1-A9FE]，717个符号，除GB2312符号外，增补10个小写罗马数字和GB12345增补符号。
 *    	5. GBK/5 扩展非汉字符号
 *    		[A840-A9A0], 166个符号，BIG-5非汉字符号、结构符和"〇"排列
 *    四字节：
 *    	[0x81-0xFE] [0x30-0x39] [0x81-0xFE] [0x30-0x39] 6530码位，6530汉字字符   CJK统一汉字扩充A
 *    	[0x95-0x98] [0x30-0x39] [0x81-0xFE] [0x30-0x39] 42711码位，42711汉字字符 CJK统一汉字扩充B
 *
 *   GB2312       = 6763个汉字  = 单字节 + 双字节(6763)
 *   GBK          = 21003个汉字 = 单字节 + 双字节(6763+6080+8160)
 *   GB18030-2000 = 27533个汉字 = 单字节 + 双字节(21003) + 四字节扩充A(6530)
 *   GB18030-2005 = 70244个汉字 = 单字节 + 双字节(21003) + 四字节扩充A(6530) + 四字节扩充B(42711)
 *
 * @see
 *   http://www.fmddlmyy.cn/text24.html
 *   http://dictionary.sensagent.com/GB%2018030/en-en/
 *   https://baike.baidu.com/item/Unicode/750500?fr=aladdin
 *   https://www.cnblogs.com/csguo/p/7401874.html
 *	 https://www.qqxiuzi.cn/bianma/zifuji.php 在线查询比较
 * @{
 */

/** @brief 判断是否满足GB的编码规则 */
bool _is_gb_byte(uint8_t ch);
bool _is_gb_byte(uint8_t ch0, uint8_t ch1);
bool _is_gb_byte(uint8_t ch0, uint8_t ch1, uint8_t ch2, uint8_t ch3);

/** @brief 判断单字节是否是GB编码，等同 _is_gb_byte */
inline bool _is_legal_gb(uint8_t ch);

/** @brief 判断两个字节是否合法的GB编码，可能为两个单字节或一个双字节 */
bool _is_legal_gb(uint8_t ch0, uint8_t ch1);

/*
 * @brief 判断四个字节是否合法的GB编码
 *  可能是四个单字节或两个双字节或一个四字
 *  节；实现方式为判断是否为两个二字节GB序列或一个四字节GB序列
 */
bool _is_legal_gb(uint8_t ch0, uint8_t ch1, uint8_t ch2, uint8_t ch3);

/** @brief 判断是否是中文字符串 */
bool _is_gb_string(const char* str, size_t len);

/** @brief 统计字符串中gb编码的个数，等同于strlen_gb */
size_t _count_gb_word(const char* str, size_t len);


#endif // Header_Guard_GUID__1DCF1EEF_661E_499A_AE94_F2D15D4299D3
